package com.xunsiya.service.system.impl;

import com.xunsiya.common.config.util.Md5Util;
import com.xunsiya.service.system.RegisterService;
import com.xunsiya.system.vo.User;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.mail.Session;
import java.util.Date;
import java.util.Properties;
import java.util.Random;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
/**
 * 用户实现层
 *
 * @author linqy
 * @version 1.0
 *          <p/>
 *          <br/>
 *          <br/>修订人    修订时间      描述信息
 *          <br/>-----------------------------------------------------
 *          <br/>linqy    2017/11/11    初始创建
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class RegisterServiceImpl implements RegisterService {
    private static Logger logger = Logger.getLogger(RegisterServiceImpl.class);
    /**
     * 本地ip
     */
    @Value("${local.ip}")
    private String localIp;
    /**
     * 邮箱服务器
     */
    @Value("${email.host}")
    private String emailHost;
    /**
     * 邮箱服务器密码
     */
    @Value("${email.password}")
    private String emailPassword;
    /**
     * 邮箱服务器smtp
     */
    @Value("${email.smtp}")
    private String emailSmtp;

    /**
     * 邮箱服务器port
     */
    @Value("${email.port}")
    private String emailPort;
    /**
     * 项目域名
     */
    @Value("${server.servlet.context-path}")
    private String contextPath;
    /**
     * 项目端口号
     */
    @Value("${server.port}")
    private String serverPort;
    /**
     * npm端口号
     */
    @Value("${server.port}")
    private String npmPort;
    /**
     * 校验码
     */
    private static final String CHECK_CODE = "checkCode";

    /**
     * 发送注册激活邮件
     * @param user
     */
    @Override
    public void sendAccountActivateEmail(User user) {
    Session session = getSession();
    MimeMessage message = new MimeMessage(session);
    try{
        message.setSubject("这是一封激活账号的邮件");
        message.setSentDate(new Date());
        //setFrom 表示用哪个邮箱发送邮件
        message.setFrom(new InternetAddress(emailHost));
      /**
      * RecipientType.TO||BCC||CC
      * TO表示主要接收人
      * BCC表示秘密抄送人
      * CC表示抄送人
      * InternetAddress  接收者的邮箱地址
      */
        message.setRecipient(Message.RecipientType.TO, new InternetAddress(user.getEmail()));
        message.setContent(user.getUserName()+"尊敬的用户您好，请点击此链接激活账号:<a href='"+generateActivateLink(user)+"'>"+generateActivateLink(user)+"</a>"
                ,"text/html;charset=utf-8");
        logger.info("激活邮件已发送到：" + user.getEmail());
        logger.info("链接激活账号：" + generateActivateLink(user));
        Transport.send(message);
    } catch (MessagingException e) {
        e.printStackTrace();
    }
}
    /**
     * 发送忘记密码邮件
     */
    @Override
    public String sendPasswordEmail(User user)
    {
        String password = "";
        Session session = getSession();
        MimeMessage message = new MimeMessage(session);
        try{
            message.setSubject("这是一封初始化密码的邮件");
            message.setSentDate(new Date());
            //setFrom 表示用哪个邮箱发送邮件
            message.setFrom(new InternetAddress(emailHost));
            /**
              * RecipientType.TO||BCC||CC
              * TO表示主要接收人
              * BCC表示秘密抄送人
              * CC表示抄送人
              * InternetAddress  接收者的邮箱地址
              */
            message.setRecipient(Message.RecipientType.TO, new InternetAddress(user.getEmail()));
            password = getStringRandom(6);
            message.setContent(user.getUserName()+"尊敬的用户您好，您初始化密码是：" + password
                    ,"text/html;charset=utf-8");
            Transport.send(message);
            logger.info("初始化密码邮件已发送到：" + user.getEmail());
        } catch (MessagingException e) {
            e.printStackTrace();
        }
        return password;
    }
    private Session getSession() {
        Properties props = new Properties();
        //指定发送的邮箱的邮箱协议
        props.setProperty("mail.transport.protocol", "smtp");
        //指定SMTP服务器
        props.setProperty("mail.smtp.host",emailSmtp);

        props.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");

        props.setProperty("mail.smtp.socketFactory.fallback", "false");
        //smtp是发信邮件服务器,端口是465
        props.setProperty("mail.smtp.port", emailPort);

        props.setProperty("mail.smtp.socketFactory.port", emailPort);
        //指定是否需要SMTP验证
        props.setProperty("mail.smtp.auth","true");

        Session session = Session.getInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                //SMTP服务器密码
                return new PasswordAuthentication(emailHost, emailPassword);
            }
        });
        return session;
    }

    /**
     * 生成激活链接
     * @param user
     * @return
     */
    private String generateActivateLink(User user) {
        logger.info("邮箱服务器host:"+emailHost);
        logger.info("邮箱服务器password:"+emailPassword);
        logger.info("邮箱服务器smtp:"+emailSmtp);
        logger.info("邮箱服务器port:"+emailPort);
        logger.info("启动npm端口:"+npmPort);
        logger.info("本地服务器IP:"+localIp);
        return "http://"+ localIp +":"+npmPort+contextPath+"#/activate?id="+user.getId()+"&"+CHECK_CODE+"="+generateCheckcode(user);
    }
    /**
      * 生成校验码，用户名+UUID唯一标识符，为安全把他们加密发送
      * @param user
      * @return
      */
    private String generateCheckcode(User user) {
        if(user != null)
        {
            return Md5Util.getMd5("MD5", 0, null,user.getUserName()+user.getCreateTime());
        }
        else
        {
            return "";
        }
    }
    /**
     * 验证校验码
     */
    @Override
    public boolean verifyCheckcode(User user, String checkCode) {
        boolean flag = generateCheckcode(user).equals(checkCode);
        return flag;
    }
    /**
     * 生成随机数字和字母
     * @param length
     * @return
     */
    private String getStringRandom(int length) {

        String val = "";
        Random random = new Random();
        //length为几位密码
        for(int i = 0; i < length; i++) {
            String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
            //输出字母还是数字
            if( "char".equalsIgnoreCase(charOrNum) ) {
                //输出是大写字母还是小写字母
                int temp = random.nextInt(2) % 2 == 0 ? 65 : 97;
                val += (char)(random.nextInt(26) + temp);
            } else if( "num".equalsIgnoreCase(charOrNum) ) {
                val += String.valueOf(random.nextInt(10));
            }
        }
        return val;
    }
}


